
本篇介紹 ES2018 (ES9) 提供的 RegExp 的 s (dotAll) flag。
本篇會有很多特殊字元,但 IT 鐵人這裡無法顯示這些字元,所以內文會看到大量的「???」XDD
. 在 RegExp 中的限制在 RegExp (regular expression,正規表達式,正規表示式) pattern 中,. (點) 可用來 match 單一的任何字元,但在 ECMAScript 有兩個例外:
. 與 astral (即非 BMP) 字元不 match. 與 line terminator 字元不 match. 與非 BMP 字元不 match. 與 astral (即非 BMP) 字元不 match,像我們常見的 emoji 就是這種字元,以「
」為例:
/^.$/.test('?');
// false
但這個問題可用 u ( unicode ) flag 來解決:
/^.$/u.test('?');
// true
註:對 ECMAScript 來說,BMP 字元就是一個字元為一個 code point,而其他非 BMP 的字元就是兩個字元,因為這些字元是兩個 code point,只要該字元是幾個 code point,就是
length幾。例如:'?'.length; // 2 '\uD83D\uDE0E' === '?'; // true
. 與 line terminator 字元不 matchline terminator 字元不與 . match,常見的有 \n 和 \r:
/^.$/.test('\n');
// false
/^.$/.test('\r');
// false
下面是在 spec 中對 line terminator 的定義:
U+000A:LINE FEED (LF) ( \n )U+000D:CARRIAGE RETURN (CR) ( \r )U+2028:LINE SEPARATORU+2029:PARAGRAPH SEPARATOR而下面在 spec 中對 white space 的定義:
U+0009:CHARACTER TABULATIONU+000B:LINE TABULATION ( \v )U+000C:FORM FEED (FF) ( \f )U+0020:SPACEU+00A0:NO-BREAK SPACEU+FEFF:ZERO WIDTH NO-BREAK SPACE但有時會根據情況,會將一些字元視為換行字元,例如:
U+000B:LINE TABULATION ( \v )U+000C:FORM FEED (FF) ( \f )U+0085:NEXT LINE這就會讓 RegExp pattern 中的 . 發生一些問題:
. 不包含某些 newline 字元例如:常見的 \n 不能被 . match:
/foo.bar/.test('foo\nbar');
// false
過去只能用一些特殊技巧來解決這個問題,例如:[\s\S] 或 [^]:
/foo[^]bar/.test('foo\nbar');
// true
/foo[\s\S]bar/.test('foo\nbar');
// true
註:在 ECMAScript spec 的定義中,RegExp pattern 中的
\s不只 match white space,也可 match line terminator。/\s/.test(' '); // true /\s/.test('\f'); // true /\s/.test('\n'); // true /\s/.test('\r'); // true